package cn.geminis.workflow.service.service.engine.interceptor;

import cn.geminis.workflow.service.service.engine.ExtensionElementUtils;
import cn.geminis.workflow.service.service.engine.expression.ExpressionValueContext;
import cn.geminis.workflow.service.service.engine.expression.GeminiExpression;
import cn.geminis.workflow.service.service.engine.expression.GeminiExpressionManager;
import cn.geminis.workflow.service.utils.SpringUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.flowable.engine.interceptor.CreateUserTaskAfterContext;
import org.flowable.engine.interceptor.CreateUserTaskBeforeContext;
import org.flowable.engine.interceptor.CreateUserTaskInterceptor;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * @author puddi
 */
@Service
@RequiredArgsConstructor
public class GeminiCreateUserTaskInterceptor implements CreateUserTaskInterceptor {

    private final GeminiExpressionManager expressionManager;

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    @Override
    @SneakyThrows
    public void beforeCreateUserTask(CreateUserTaskBeforeContext taskContext) {
        var valueContext = SpringUtils.getBean(ExpressionValueContext.class)
                .withTask(taskContext)
                .withProcess(taskContext.getExecution().getProcessInstanceId());

        var descriptionObject = new HashMap<String, String>();
        descriptionObject.put("processName", (String) ((Map<String, Object>) valueContext.getVariables().get("process")).get("name"));
        taskContext.setDescription(OBJECT_MAPPER.writeValueAsString(descriptionObject));

        ExtensionElementUtils.get(taskContext.getUserTask().getExtensionElements(), "dataUrl")
                .ifPresent(dataUrl -> {
                    if (StringUtils.hasText(dataUrl)) {
                        var dataUrlExpression = ((GeminiExpression) expressionManager.createExpression(dataUrl));
                        dataUrl = (String) dataUrlExpression.getValue(null);
                        valueContext.withData(dataUrl);
                    }
                });

        var formKey = taskContext.getFormKey();
        if (StringUtils.hasText(formKey)) {
            var expression = (GeminiExpression) expressionManager.createExpression(formKey);
            var formUrl = (String) expression.getValue(null);
            taskContext.setFormKey(formUrl);
        }

        ExtensionElementUtils.get(taskContext.getUserTask().getExtensionElements(), "instanceName")
                .ifPresent(nameTemplate -> {
                    if (StringUtils.hasText(nameTemplate)) {
                        var nameExpression = expressionManager.createExpression(nameTemplate);
                        var name = (String) nameExpression.getValue(null);
                        taskContext.setName(name);
                    }
                });
    }

    @Override
    public void afterCreateUserTask(CreateUserTaskAfterContext createUserTaskAfterContext) {

    }
}
